import React, { Fragment, useMemo, useRef, useImperativeHandle, useEffect, useCallback } from 'react';
import Success from './Icon/Success';
import Error from './Icon/Error';
import { classListAdd } from '@y.dsh/utils/lib/dom';
import { DownProps, DownMethods } from '../types';

function Down(props: DownProps, ref: any): JSX.Element {
  const { status, offset, outOffsetRate } = props;

  const downRef = useRef<HTMLDivElement | null>(null); // 下拉刷新盒子容器
  const dragInnerRef = useRef<SVGSVGElement | null>(null); // 下拉SVG
  const dragCircleRef = useRef<SVGCircleElement | null>(null); // 下拉的圆
  const perimeter = useMemo(() => Math.PI * 300, []); // 下拉圆的周长
  const fontSize = useMemo(() => 20, []); // 下拉刷新文字的高度
  const beginShowHeight = useMemo(() => offset - fontSize, [offset, fontSize]); // 开始显示圆的下拉高度
  const showMaxPerimeter = useMemo(() => perimeter * 0.8, [perimeter]); // 显示的最大圆周长
  const rotate = useRef(-90); // 旋转角度 等同于css默认已经旋转了的角度

  const getRefreshDOM = useMemo(() => {
    if ([1, 2, 3, 4, 6].indexOf(status) > -1) {
      return (
        <Fragment key="refresh">
          <svg
            ref={dragInnerRef}
            className="easy-scroll-down-inner-refresh"
            viewBox="0 0 400 400"
            width="1em"
            height="1em"
          >
            <circle
              ref={dragCircleRef}
              cx="200"
              cy="200"
              r="150"
              strokeWidth="30"
              stroke="currentColor"
              strokeOpacity="0"
              fill="transparent"
              strokeDashoffset={perimeter}
              strokeDasharray={`${perimeter},${perimeter}`}
            />
          </svg>
          <span className="easy-scroll-down-inner-text">
            {(() => {
              if (status === 1) {
                return '下拉刷新'
              }
              if (status === 2) {
                return '释放刷新'
              }
              if (status === 3) {
                return '马上刷新'
              }
              if (status === 4) {
                return '正在刷新'
              }
              if (status === 6) {
                return '我回去咯'
              }
            })()}
          </span>
        </Fragment>
      )
    }
    if (status === 5) {
      return (
        <Fragment key="success">
          <Success
            fontSize="inherit"
            animation
          />
          <span className="easy-scroll-down-inner-text">刷新成功</span>
        </Fragment>
      )
    }
    if (status === 7) {
      return (
        <Fragment key="error">
          <Error
            fontSize="inherit"
            animation
          />
          <span className="easy-scroll-down-inner-text">刷新失败</span>
        </Fragment>
      )
    }
    return null
  }, [status, perimeter]);

  const setRotate = useCallback(() => {
    // 无限旋转
    if (dragInnerRef.current) {
      rotate.current += 9000;
      dragInnerRef.current.style.transform = `rotate(${rotate.current}deg)`;
    }
  }, []);
  useEffect(() => {
    let timer: NodeJS.Timeout | null = null;
    if (status === 4 && dragInnerRef.current) {
      // 正在刷新启用无限旋转
      classListAdd(dragInnerRef.current, 'easy-scroll-down-inner-refreshing');
      setRotate();
      timer = setInterval(() => {
        setRotate();
      }, 20000);
    }
    return () => {
      if (timer !== null) {
        clearInterval(timer);
        timer = null;
      }
    }
  }, [status, setRotate]);

  useImperativeHandle<any, DownMethods>(ref, () => ({
    setHeight(height) {
      if (dragCircleRef.current) {
        if (height >= fontSize) {
          // 如果高度超出了最低限 开始计算周长 这样可以确保用户能清楚的看到圆弧成长的整个过程
          let cp = (showMaxPerimeter / beginShowHeight) * (height - fontSize); // 计算周长
          if (cp > showMaxPerimeter) { // 周长限定的最大值
            cp = showMaxPerimeter;
          }
          let opacity = cp / perimeter + 0.2; // 计算透明度 从0.2开始
          if (opacity > 0.9) { // 不允许超过限度
            opacity = 0.9;
          }
          dragCircleRef.current.style.strokeOpacity = `${opacity}`; // 透明度
          dragCircleRef.current.style.strokeDashoffset = `${perimeter - cp}px`; // 圈大小
        } else {
          // 如果没达到要求置为不可显示状态
          dragCircleRef.current.style.strokeOpacity = '0';
          dragCircleRef.current.style.strokeDashoffset = `${perimeter}px`;
        }
        if (height > offset && status === 2 && dragInnerRef.current) {
          // 超过了临界值 并且还在下拉 开始旋转效果
          rotate.current = -90 + (height - offset) / outOffsetRate;
          dragInnerRef.current.style.transform = `rotate(${rotate.current}deg)`;
        }
      }
      // 设置下拉刷新盒子高度
      if (downRef.current) {
        downRef.current.style.height = `${height}px`;
      }
    }
  }));

  return (
    <div
      ref={downRef}
      className="easy-scroll-down easy-scroll-hardware"
    >
      <div
        className="easy-scroll-down-inner easy-flex-center"
        style={{ fontSize }}
      >
        {getRefreshDOM}
      </div>
    </div>
  )
}

export default Down
